from enum import Enum, unique

from yysautomatic.log import get_logger

logger = get_logger(__name__)


@unique
class EventType(Enum):
    """
    事件类型
    """

    SHOW = 'show'


class EventObject(object):

    def __init__(self, source, frame):
        self.source = source
        self.frame = frame


class EventManager(object):

    def __init__(self, frame):
        self.__source_listener_dict = dict()
        self.__frame = frame

    def sources(self, event_type):
        if event_type not in self.__source_listener_dict:
            return []
        return [source for (source, listeners) in self.__source_listener_dict[event_type]]

    def add_listener(self, event_type, source, listener):
        """
        添加事件
        :param event_type:
        :param source:
        :param listener:
        :return:
        """
        if event_type not in self.__source_listener_dict:
            self.__source_listener_dict[event_type] = []
        for (s, listeners) in self.__source_listener_dict[event_type]:
            if s == source:
                listeners.append(listener)
                return
        self.__source_listener_dict[event_type].append((source, [listener]))

    def remove_listener(self, event_type, source, listener):
        """
        移除事件
        :param event_type:
        :param source:
        :param listener:
        :return:
        """
        if event_type in self.__source_listener_dict:
            for (s, listeners) in self.__source_listener_dict[event_type]:
                if s == source:
                    listeners.remove(listener)

    def trigger(self, event_type, sources):
        """
        触发事件
        :param event_type:
        :param sources:
        :return:
        """
        if event_type not in self.__source_listener_dict:
            return
        execute_listeners = []
        for (s, listeners) in self.__source_listener_dict[event_type]:
            if s in sources:
                for listener in listeners:
                    try:
                        if listener not in execute_listeners:
                            listener(EventObject(s, self.__frame))
                            execute_listeners.append(listener)
                    except Exception as e:
                        logger.error(e)
